1. Field of the Invention
The invention relates to computer software frameworks, and more specifically to generic software frameworks that are usable to allow a software developer to create secure, scalable, and widely distributed applications, applications that may be distributed over an internal network or even externally over the public internet without requiring a developer to create the pieces of the application that provide for any combination of these features from scratch. The invention also relates to methods for developing software frameworks as well as to applications created using such frameworks.
2. Description of the Related Art
The invention is directed to a software framework suitable for creating and maintaining secure, scalable, and distributed applications between a centralized server (or many server computers acting as a unit) and a plurality of clients or end-users. One example of an application that most people are familiar with and that could be implemented using this invention without even coming close to utilizing its full capabilities is a website application that enables people (end-users) to examine merchandise (e.g., books or CDs/DVDs) over the internet; then, place some of these books or CDs in their virtual “shopping cart”; and then, pay for them, all from within their internet browser. In this example, the end-users are the customers of the company (e.g., XYZ Book and Media, Inc.) that developed this website. The end-users are the people who, through their browsers, will examine XYZ's merchandise and possibly place items in their cart and execute purchases. The collection of screens, entry forms, etc. that will be presented to the end-users (or customers of XYZ) constitute the GUI (or Graphical User Interface) through which these end-users can interact with XYZ's application. Note that GUIs are not always run from inside web browsers, and much content that comes through a web browser would not be considered a “true” GUI (at least inasmuch as what is meant by a GUI for the purposes of this patent application). Much of the information that comes through web-browsers is in the form of raw web pages that have no operational logic and are simply displayed as received by the browser. Even the forms on web pages may not be dynamic in that they directly transmit to the server only exactly what the end-user types back (when the user presses a “Submit”-type of button). In fact, this shopping cart application, as described so far, could (and frequently is), on the client side, handled in just such a fashion, i.e.: without requiring XYZ to develop a “true” GUI for the client side.
A GUI (for the purposes of this patent application) shall mean a full-featured, window-based interface that is created and managed by a computer program. If XYZ had created a full featured GUI for this application, it would be able to send compact information back to the GUI in response to each request rather than an entire page to display. The GUI program executing on the client side (on the end-user's machine) would be able to take appropriate action—possibly just displaying, e.g., the ‘total cost after shipping’ in an area of its window (as opposed to having an entire new page sent back which had all the information on the original page, but additionally had the ‘total cost after shipping’ information). If XYZ developed a full-featured GUI on the client side, it would be able to offer the end-user far more advanced content and capability as well as a far more usable (user-friendly) interface. E.g., Suppose that XYZ did not just service retail clients, but serviced book and media stores all over the country, supplying them with inventory. In this case, when a hot new DVD or book comes out, XYZ might wish to display to its book and media store end-users (all of whom would probably be interested in ordering some quantity of these items), a real-time count of how many of each of the items XYZ has remaining in inventory. As XYZ's customers (end-users) place orders (using their GUIs), every other customer's GUI (where a customer is watching one of the items that is ordered) must be somewhat instantaneously updated with the new inventory information for that item.
Of course, with a simple web page on the client side it would be possible for the end-user to click a refresh-type button whenever he/she wanted to ascertain how many of a particular item remained; and, in so doing, said end-user would cause the entire page with the inventory count of the items he/she was watching to be rebuilt on the server and sent back with updated counts (as of the time it was built). Nonetheless, let us just suppose that having a real-time inventory count of items of interest was somehow important to XYZ's clients (i.e., to the end-users of XYZ's application) and that, therefore, developing such an application would provide XYZ with a competitive advantage.
Before we proceed, we should also mention that another way of accomplishing this (without writing the difficult-to-develop, full-featured, supporting GUI and server side code that this invention generically supplies) is to use javascript (no relationship to Java) or some other method of having a semi-automated web-page that might poll the server every n seconds to supply an updated web page (or piece of a web page) containing the updated inventory of all items that a particular end-user happened to be watching. Such a ‘GUI’ would not qualify as the type of full-featured interface that is meant when we refer to the full-featured GUI functionality that this invention facilitates. For one thing, polling is an inferior technique as it is inherently not scalable—imagine thousands of users calling on the server side code every few seconds and forcing it to reply whether or not the few of the thousands of items that a particular end-user happened to be watching had an inventory count change. By contrast, with the type of full-featured GUI functionality (and supporting server-side functionality) that the inventive framework generically supplies, it is possible to notify (and, for example, cause the display code to execute on) only those GUIs where a change to a watched inventory item occurred.
Somehow, XYZ's central application (i.e. the code it has written to run on the server side) must be able to notify all end-user (client side) GUIs that are “interested” whenever an item is ordered. As already mentioned, while a simple set of web pages on the client side could be used if we asked the end-users to press a button (thereby demanding a new page) every time they wanted to see updated inventory, only an application (program) on the client side would be capable of receiving and updating this information in real-time. A full-featured application (GUI in this example) on the client-side would be able to execute code upon receiving such “real-time” information—displaying only the changed information and perhaps taking other actions (like turning the entire background of the GUI red if an observed item dropped below the particular end-user's supplied threshold, or even placing an order for the remaining inventory in such a situation).
Some of the aforementioned handling of real-time information may simply read like the conventional “publish-subscribe” type of functionality already available in a number of commercial products like those from many vendors that implement Sun's JMS specification or IBM's MQ-Series product. But, while the inventive framework does, among many possible uses, enable implementers to seamlessly provide a publish-subscribe capability within their own code (and without writing multi-threaded code on the client or server side):
1—The inventive framework does not provide a publish-subscribe service; also
2—The mechanism within the inventive framework that renders providing a publish-subscribe service so trivial has nothing to do with these aforementioned technologies. I.e., the capability that the inventive framework provides to an implementer, which renders providing a publish-subscribe capability within their application trivial, is the same mechanism that renders providing all other features (including multi-threading within a single connection) trivial.
Finally, conventionally, only an application on the client side could perform complex field level actions whereby each field on the screen was “validated” after an end-user entered it, and, at times, programmatically complex actions taken. The end-user would not wait for the entire information on the GUI to be sent back to the server for the server to send another form back indicating which fields needed to be changed/supplied (as they would if a form were used rather than a full-featured GUI). A full-featured GUI might not enable a “submit”-type button until information was properly filled in. A full-featured GUI could take immediate action dependent on the information that an end-user entered into a particular field (as opposed to waiting for an entire form to be submitted). E.g.: If the user checked off certain categories for recently released DVDs, an on-screen scrolling list could be adjusted automatically to be filled with only the DVDs that met their criteria. This would be accomplished by the GUI application (program) running on the client side sending a command to the server every time a category was checked or unchecked.
Each time XYZ's program running on the server side (the program responsible for receiving, executing, and sending back results to all XYZ's clients that are running the client side GUI program) receives a command to re-form a new list of DVDs based on all of the categories checked. The server consults its inventory and re-forms the list to choose from and sends just that list back to the GUI (client side program) for re-display in the list presented to the end user. If and when the end user makes a selection, the server might be sent a different command (e.g.: “sendDetailOn:DVD:134502”) to which it might respond with a full description to be displayed by the client side GUI program in the detail window on that GUI (screen).
By having a full-featured program controlling the interface on the client side, XYZ can obtain far greater functionality and usability than it could if the client side were dependent on only forms that the browser knew nothing about (but was capable of rendering and using them to collect information an entire form at a time).
To recap, a GUI, as we will use that term here, is an executing program that runs on the client side (on end-users' computers), that provides a windowed interface, and that enables the end-users of an application to interact (send commands to and receive responses and information from) XYZ's application running in a central location (i.e., on the server-side). The functionality that a GUI program can offer on the client-side is always a superset of what could be offered by web-pages. Alternatively stated, anything that can be accomplished using web pages as the end-user interface can be accomplished by providing a GUI either through or independently of a web-browser, but the reverse is not true. A GUI-based interface (that is an executing program) can provide greater functionality (and a better presentation/user experience even when considering functionality that could be provided by both).
The above description begins to discuss how a single end-user, i.e., client of XYZ, (using the client side GUI) would interact with the code that XYZ wrote on the server side. To be more complete, here are the required steps:
1—Client GUI must establish a connection or a secure connection over the network (or Internet) to the code developed by XYZ executing on XYZ's centralized servers. (Of course, this connection does not have to be secure, but as the vast majority of distributed application implementers would desire this, and since the inventive framework seamlessly provides for robust security, we will assume that, in fact, the connection must be secure.)
2—Client GUI will send commands to the server (like orders or requests to see certain inventory) when an end-user takes an action on the client GUI presented to him/her. The server code must interpret and execute these commands and then send a response back.
3—Client GUI may request to receive information from the server asynchronously (i.e., not as the result of the end-user taking an action, as in 2 above, but real-time information like the inventory level of certain items in our example). Server will send information to this (and other client GUIs) every time there is a change.
There are many examples of widely distributed, Internet-based applications that are well known, such as: the web sites of: Fresh Direct, a grocery shipment service; Amazon, the on-line book, music, electronics distribution company that operates a site that is a good example of such an application; and, of more relevance when considering some of the more advanced capabilities that this invention provides, the site of Island that, at that time, had a Java-based applet that received real-time stock price updates for those equities that a particular end-user might be watching. In some instances, such applications are created entirely from scratch, including all of the communications and security software implemented to allow end-users to contact the central server and place an order. In many cases (including the aforementioned), the established level of security would not meet the level required to carry out a large-scale financial transaction or to maintain patients' medical records over the Internet. It would be desirable if software developers could simply write server-side code and client-side code and not have to worry about how the two will communicate/communicate securely, thereby freeing up their attention solely to the look and feel of the client GUI and the functionality (i.e., the business logic specific to the application) of the server.
One existing open specification for a framework is Enterprise Java Beans or EJB developed by Sun Microsystems, Inc. EJB makes the design and implementation of a client-server application much easier than if one were starting from scratch since it provides for much of the connectivity structure of an application in building block fashion. EJB essentially allows a system designer to write client-side code and server-side code and not have to worry how the client-server communication is effected; the framework takes care of most of the nuts and bolts of connectivity.
However, EJB has many functional and design limitations:
EJB only enables single-threaded communications between client and server, and while it might be possible for the implementer to multi-thread their client themselves, this would still not provide often needed functionality as EJB also provides for only synchronous communications whereby a client thread sends a request to the server and must wait for a response, and there is no way for the client to receive information (like real-time market information or an alert from a patient's heart monitor) asynchronously.
EJB also does not allow purchaser's server-side code to be multi-threaded (which has the effect of preventing an implementer's server-side code from spawning a process that runs after the server-side code returns). In many types of applications, this is highly undesirable and severely limits the capabilities of a system utilizing EJB.
EJB requires multiple and unnecessarily complex development steps and compilation phases for a purchaser's server-specific code: In addition to developing the server-specific code (which is all that should be necessary), an implementer must develop a home class, a remote interface and a deployment descriptor; must package these up in a jar; must perform multiple steps to deploy the bean to the server; must have a JNDI (Java Naming and Directory Interface) service running and must register the home class with that, etc. The process of developing, maintaining and enhancing code is difficult, time-consuming and inefficient.
Also, EJB uses RMI (Remote Method Invocation) as its underlying transport mechanism (a CORBA-type of technology) which requires the marshaling and unmarshaling of objects. This is very expensive from a performance standpoint, especially if message traffic between client and server is heavy as might be the case if real-time data were being sent to a GUI; or, as might be the case if a system interface to enable access of the implementer's server-side code from another system was acting as the client (instead of a GUI being the client), and that system interface (through this invention) was sending or receiving large amounts of information. It is also expensive from a bandwidth standpoint, as it is only the data in the object being sent that is really needed, not an entire serialized object description, which is what is sent via RMI.
Stateful (server-side) code is code that maintains information after the command is executed (and after results have already been returned to the client) so that, when a client sends subsequent requests, the server-side code can build on (or make use of) information from commands/requests that executed before. With stateless server-side code, every command stands on its own. As an example, a “shopping cart” type application would require stateful server-side code if every time an end-user sent a command to add an item to his/her cart, the server-side code simply maintained the contents of the cart from previous requests. If stateless code were used for this purpose, the entire contents of the cart would either have to be maintained and transmitted by the client with each and every request, OR, the server side code might persist the contents of the cart (to memory or disk) after every request—returning some sort of session id to the client so that the client could transmit this session ID with each subsequent request, which server-side code could then use to retrieve the cart contents prior to executing the current command. While it may appear from the above example that one could always use the stateless server-side code; and that, indeed, it might even be desirable to use this simpler approach, there are many applications where a more complex, stateful approach would be required. Certainly, any type of trading application where each end-user is monitoring his/her position and watching prices of selected instruments would require a stateful approach and a persistent connection. In this case, server-side code written by the implementer would need to actively stay alive (even between satisfying end-user requests) as it would be too time-consuming to restore state, reestablish positions, establish what was being watched, and re-subscribe to real-time market information with every new request. Also, if real-time prices of market instruments were being continually sent back to the end-user's GUI, it would be impossible to accomplish this without a persistent connection.
While EJB supports both stateful and stateless server-side code, it is very inefficient with stateful code, and it is incapable of the type of asynchronous communication desired.
Because stateful EJB Beans can be “passivate( )d” (i.e., made dormant and swapped out to disk without the code's consent) by the EJB container, even if the EJB bean (i.e., the server-specific code developed for an EJB framework) were to attempt to circumvent the multi-threading restriction by sending a message to a multi-threaded server (that was not an EJB implementation) to process, and then returned, it would not necessarily be able to receive the result from the server that it passed the request to, because it (the EJB bean) might have been passivate( )d before the response was received back. Therefore, the server that was passed the request might have to wait until the stateful bean was reactivated by its client and retrieved the message back, such a system would be highly non-performant and undesirable.
While EJB Containers (i.e., the framework code in an EJB framework) MAY create a pool of server-specific code instances (i.e., EJB Beans) to handle stateless connections, stateful sessions typically require expensive newInstance( ) calls to reallocate and recreate the object when a session is restored. Not only do server-specific components developed by the implementer need to be reinstantiated and reinitialized, but many of the internal framework components (like the EJBObject that the EJB Container creates to act as a middleman for the communication between server and client must be recreated with each new connection, and with this EJB Object needlessly passing communication through the EJB Container at each step).
Additionally, security concerns are not addressed adequately by EJB, a critical flaw. In many systems, secure communication is vital to prevent theft of bank account numbers, corporate records, and other highly sensitive information. For many complex systems, especially those to be made available over the public internet and/or where high value transactions are executed or applications are designed to provide access to highly sensitive information, the importance of keeping data secure is even higher. Examples of systems where a higher level of security would be needed in order to transact over the public internet would include a system where financial institutions could trade government securities; a medical records system (where patients' records were accessible over the public internet), etc. While there exist other technologies that an implementer could perhaps tie in and use for security while using EJB solely on the server-side, an implementer using EJB in this manner would still have to expend the time and effort and experience the difficulties of dealing with complex security issues and code to address these issues, as well as undertake integrating several complex technologies.
Finally, from the standpoint of developers trying initially to approach this technology, books which teach EJB are typically many hundreds of pages thick and require days or weeks of review before a software designer could begin to make use of the EJB framework.
In short, while EJB has helped create an environment that serves to provide developers with some of the software infrastructure necessary to create distributed software applications, EJB has significant shortcomings.